﻿using AutoMapper;
using Essensoft.AspNetCore.Payment.Alipay;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NewRetail.Application.Components.Platform;
using NewRetail.Application.Components.Platform.Entity;
using NewRetail.Application.Components.StoreValueCard.Entity;
using NewRetail.Application.Components.StoreValueCard.Model;
using NewRetail.Application.Components.WeChat.Configurations;
using NewRetail.Application.Components.WeChat.Services.HttpClients;
using NewRetail.Application.Core.Entity;
using NewRetail.Application.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;

namespace NewRetail.Application.Components.StoreValueCard.Services
{
    #region 接口
    /// <summary>
    /// 接口
    /// </summary>
    public interface IStoreValueCardService : IApplicationService
    {
        #region 储值卡相关

        /// <summary>
        /// 创建充值方案
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        Task<(int, string)> CreateRechargeSchemeAsync(RechargeSchemeRequestDto inputDto);
        /// <summary>
        /// 更新充值方案
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        Task<(string, string)> UpdateRechargeSchemeAsync(UpdateRechargeSchemeRequestDto inputDto);
        /// <summary>
        /// 删除充值方案
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        Task<(string, string)> DeleteRechargeSchemeAsync(string id);
        /// <summary>
        /// 获取充值方案列表
        /// </summary>
        /// <param name="searchDto"></param>
        /// <returns></returns>
        Task<(IEnumerable<RechargeSchemeShowDto>, int, bool)> GetRechargeSchemes(RechargeSchemeSearchDto searchDto);
        /// <summary>
        /// 根据Id获取充值方案
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        Task<(RechargeSchemeShowDto, string)> GetRechargeSchemeById(string id);
        /// <summary>
        /// 获取充值记录列表
        /// </summary>
        /// <param name="searchDto"></param>
        /// <returns></returns>
        Task<(IEnumerable<RechargeRecordShowDto>, int, bool)> GetRechargeRecords(RechargeRecordSearchDto searchDto);
        /// <summary>
        /// 更新充值记录订单状态
        /// </summary>
        /// <param name="searchDto"></param>
        /// <returns></returns>
        Task<(bool, string)> UpdateRechargeRecordStatus(RechargeRecordUpdateStatusDto inputDto);
        /// <summary>
        /// 储值卡充值更新余额
        /// </summary>
        /// <param name="inputDto"></param>
        /// <param name="side">0: pos终端  1:后台管理</param>
        /// <returns></returns>
        Task<(bool, string)> UpdateRechargeRecordBalance(RechargeRecordUpdateBalanceDto inputDto, int side = 0);
        /// <summary>
        /// 储值卡余额使用-更新余额（仅供POS端使用）
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        Task<(bool, string)> UpdateCardBalanceChange(CardUpdateBalanceChangeDto inputDto);
        /// <summary>
        /// 获取储值卡余额变化列表
        /// </summary>
        /// <param name="searchDto"></param>
        /// <returns></returns>
        Task<(IEnumerable<CardBalanceChangesShowDto>, int, bool)> GetCardBalanceChanges(CardBalanceChangeSearchDto searchDto);

        #endregion
    }
    #endregion

    #region 实现
    /// <summary>
    /// 实现储值卡
    /// </summary>
    public class StoreValueCardService : ApplicationService, IStoreValueCardService
    {
        #region Field
        private readonly ILogger _logger;
        //private readonly IAlipayClient _client;
        //private readonly IOptions<AlipayOptions> _optionsAccessor;
        //private readonly WxpayOptions _wechatPayOptions;
        //private readonly IWechatTenpayHttpClientFactory _wechatTenpayHttpClientFactory;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        protected IEntityHelper _entityHelper => this.LazyServiceProvider.LazyGetRequiredService<IEntityHelper>();
        protected INoGeneratorService _noGeneratorService => this.LazyServiceProvider.LazyGetRequiredService<INoGeneratorService>();
        private readonly IRepository<CardRechargeSchemeEntity> _cardRechargeSchemeRepository;
        private readonly IRepository<CardRechargeRecordEntity> _cardRechargeRecordRepository;
        private readonly IMapper _mapper;
        private readonly IRepository<PosMember> _posMemberRepository;
        private readonly IRepository<CardBalanceChangeEntity> _cardBalanceChangeRepository;
        private readonly IWebHostEnvironment _environment;
        #endregion

        #region Constructor
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="cardRechargeSchemeRepository"></param>
        /// <param name="cardRechargeRecordRepository"></param>
        /// <param name="mapper"></param>
        /// <param name="unitOfWorkManager"></param>
        /// <param name="posMemberRepository"></param>
        /// <param name="cardBalanceChangeRepository"></param>
        /// <param name="logger"></param>
        public StoreValueCardService(/*IOptions<AlipayOptions> optionsAccessor, IAlipayClient client, IOptions<WxpayOptions> wechatPayOptions,
            IWechatTenpayHttpClientFactory wechatTenpayHttpClientFactory,*/ IRepository<CardRechargeSchemeEntity> cardRechargeSchemeRepository,
            IRepository<CardRechargeRecordEntity> cardRechargeRecordRepository, IMapper mapper, IUnitOfWorkManager unitOfWorkManager,
            IRepository<PosMember> posMemberRepository, IRepository<CardBalanceChangeEntity> cardBalanceChangeRepository,
            ILogger<StoreValueCardService> logger, IWebHostEnvironment environment)
        {
            //_client = client;
            //_optionsAccessor = optionsAccessor;
            //_wechatPayOptions = wechatPayOptions.Value;
            //_wechatTenpayHttpClientFactory = wechatTenpayHttpClientFactory;
            _cardRechargeSchemeRepository = cardRechargeSchemeRepository;
            _cardRechargeRecordRepository = cardRechargeRecordRepository;
            _mapper = mapper;
            _unitOfWorkManager = unitOfWorkManager;
            _posMemberRepository = posMemberRepository;
            _cardBalanceChangeRepository = cardBalanceChangeRepository;
            _logger = logger; 
            _environment = environment;
        }
        #endregion

        #region method        

        #region 储值卡相关

        #region 创建充值方案
        /// <summary>
        /// 创建充值方案
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<(int, string)> CreateRechargeSchemeAsync(RechargeSchemeRequestDto inputDto)
        {
            var result = 0;
            var errMsg = "";
            var rechargeAmount = inputDto.rechargeAmount;
            var giftAmount = inputDto.giftAmount;
            //获取充值方案
            var db = await _cardRechargeSchemeRepository.GetDbContextAsync();
            var cardRechargeScheme = await db.Set<CardRechargeSchemeEntity>().AsNoTracking().FirstOrDefaultAsync(x => x.rechargeAmount == rechargeAmount);
            //如果不存在就新增
            if (cardRechargeScheme == null)
            {
                cardRechargeScheme = new CardRechargeSchemeEntity();
                cardRechargeScheme.rechargeAmount = rechargeAmount;
                cardRechargeScheme.giftAmount = giftAmount;
                _entityHelper.InitEntity(cardRechargeScheme);
                await _cardRechargeSchemeRepository.InsertAsync(cardRechargeScheme, autoSave: true);
                result = 1;
            }
            else
                errMsg = "充值金额已经存在";

            return (result, errMsg);
        }
        #endregion

        #region 更新充值方案
        /// <summary>
        /// 更新充值方案
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<(string, string)> UpdateRechargeSchemeAsync(UpdateRechargeSchemeRequestDto inputDto)
        {
            var id = inputDto.Id;
            var rechargeAmount = inputDto.rechargeAmount;
            var giftAmount = inputDto.giftAmount;
            try
            {
                //获取充值方案
                var db = await _cardRechargeSchemeRepository.GetDbContextAsync();
                var cardRechargeScheme = await db.Set<CardRechargeSchemeEntity>().AsNoTracking().FirstOrDefaultAsync(x => x.rechargeAmount == rechargeAmount && x.IsDeleted == false);
                if (cardRechargeScheme != null)
                {
                    cardRechargeScheme.rechargeAmount = rechargeAmount;
                    cardRechargeScheme.giftAmount = giftAmount;
                    _entityHelper.SetUpdationInfo(cardRechargeScheme);
                    await _cardRechargeSchemeRepository.UpdateAsync(cardRechargeScheme, autoSave: true);

                    return ("更新成功", null);
                }
                else
                {
                    return (null, "没有要更新的方案");
                }
            }
            catch (Exception e)
            {
                return (null, e.Message);
            }
        }
        #endregion

        #region 删除充值方案
        /// <summary>
        /// 删除充值方案
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<(string, string)> DeleteRechargeSchemeAsync(string id)
        {
            try
            {
                var db = await _cardRechargeSchemeRepository.GetDbContextAsync();
                var cardRechargeScheme = await db.Set<CardRechargeSchemeEntity>().AsNoTracking().FirstOrDefaultAsync(x => x.Id == id && x.IsDeleted == false);
                if (cardRechargeScheme != null)
                {
                    cardRechargeScheme.updateTime = DateTime.Now;
                    cardRechargeScheme.IsDeleted = true;
                    _entityHelper.SetUpdationInfo(cardRechargeScheme);
                    await _cardRechargeSchemeRepository.UpdateAsync(cardRechargeScheme, autoSave: true);
                    return ("删除成功", null);
                }
                else
                {
                    return (null, "没有要删除的奖品");
                }
            }
            catch (Exception e)
            {
                return (null, e.Message);
            }
        }
        #endregion

        #region 获取充值方案列表
        /// <summary>
        /// 获取充值方案列表
        /// </summary>
        /// <param name="searchDto"></param>
        /// <returns></returns>
        public async Task<(IEnumerable<RechargeSchemeShowDto>, int, bool)> GetRechargeSchemes(RechargeSchemeSearchDto searchDto)
        {
            int pageIndex = searchDto.PageIndex;
            int pageSize = searchDto.PageSize;
            int total = 0;
            var isLastPage = false;

            var db = await _cardRechargeSchemeRepository.GetDbContextAsync();
            var cardRechargeSchemes = await db.Set<CardRechargeSchemeEntity>().AsNoTracking().Where(x => x.IsDeleted == false).OrderBy(x => x.rechargeAmount).ToListAsync();

            total = cardRechargeSchemes.Count();
            //总页数
            var pageCount = (total + pageSize - 1) / pageSize;
            //是否最后一页
            isLastPage = pageCount <= pageIndex;
            cardRechargeSchemes = cardRechargeSchemes.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

            var objRet = _mapper.Map<IEnumerable<RechargeSchemeShowDto>>(cardRechargeSchemes);

            return (objRet, total, isLastPage);
        }

        #endregion

        #region 根据Id获取充值方案
        /// <summary>
        /// 根据Id获取充值方案
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<(RechargeSchemeShowDto, string)> GetRechargeSchemeById(string id)
        {
            //根据Id查出详情
            var db = await _cardRechargeSchemeRepository.GetDbContextAsync();
            var cardRechargeScheme = await db.Set<CardRechargeSchemeEntity>().AsNoTracking().FirstOrDefaultAsync(x => x.Id == id && x.IsDeleted == false);
            if (cardRechargeScheme == null)
            {
                return (null, "未找到记录");
            }
            else
            {
                var objRet = _mapper.Map<RechargeSchemeShowDto>(cardRechargeScheme);

                return (objRet, null);
            }
        }

        #endregion

        #region 获取充值记录列表
        /// <summary>
        /// 获取充值记录列表
        /// </summary>
        /// <param name="searchDto"></param>
        /// <returns></returns>
        public async Task<(IEnumerable<RechargeRecordShowDto>, int, bool)> GetRechargeRecords(RechargeRecordSearchDto searchDto)
        {
            var openId = searchDto?.OpenId;
            var memberNo = searchDto?.MemberNo;
            var memberTel = searchDto?.MemberTel;
            int pageIndex = searchDto.PageIndex;
            int pageSize = searchDto.PageSize;
            int total = 0;
            var isLastPage = false;

            var db = await _cardRechargeRecordRepository.GetDbContextAsync();
            var cardRechargeRecords = await db.Set<CardRechargeRecordEntity>().AsNoTracking().OrderByDescending(x => x.addTime).ToListAsync();

            if (!string.IsNullOrEmpty(openId))
                cardRechargeRecords = cardRechargeRecords.Where(x => x.openId == openId).ToList();

            if(!string.IsNullOrEmpty(memberNo))
                cardRechargeRecords = cardRechargeRecords.Where(x => x.memberNo == memberNo).ToList();

            if (!string.IsNullOrEmpty(memberTel))
            {
                var posMembers = await db.Set<PosMember>().AsNoTracking().Where(x => x.memberTel != null && x.memberTel.Contains(memberTel)).ToListAsync();
                var memberIds = posMembers.Select(s => s.Id).ToList();
                cardRechargeRecords = cardRechargeRecords.Where(x => memberIds != null && memberIds.Contains(x.memberId)).ToList();
            }

            total = cardRechargeRecords.Count();
            //总页数
            var pageCount = (total + pageSize - 1) / pageSize;
            //是否最后一页
            isLastPage = pageCount <= pageIndex;
            cardRechargeRecords = cardRechargeRecords.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

            var objRet = _mapper.Map<IEnumerable<RechargeRecordShowDto>>(cardRechargeRecords);

            return (objRet, total, isLastPage);
        }

        #endregion

        #region 更新充值记录订单状态(仅供手机端充值使用)
        /// <summary>
        /// 更新充值记录订单状态
        /// </summary>
        /// <param name="searchDto"></param>
        /// <returns></returns>
        public async Task<(bool, string)> UpdateRechargeRecordStatus(RechargeRecordUpdateStatusDto inputDto)
        {
            var rechargeStatus = inputDto.rechargeStatus;
            if (!Enum.IsDefined(typeof(EnumOrderStatus), rechargeStatus))
                return (false, "状态不正确");
            var result = await UpdateRechargeRecordStatusByCond(inputDto);
            return (result, null);
        }

        #endregion

        #region 储值卡充值更新余额
        /// <summary>
        /// 储值卡充值更新余额
        /// </summary>
        /// <param name="inputDto"></param>
        /// <param name="side">0: pos终端  1:后台管理</param>
        /// <returns></returns>
        public async Task<(bool, string)> UpdateRechargeRecordBalance(RechargeRecordUpdateBalanceDto inputDto, int side = 0)
        {
            var result = await UpdateRechargeRecordBalanceByCond(inputDto, side);
            return (result.Item1, result.Item2);
        }

        #endregion

        #region 储值卡余额使用-更新余额（仅供POS端使用）
        /// <summary>
        /// 储值卡余额使用-更新余额（仅供POS端使用）
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<(bool, string)> UpdateCardBalanceChange(CardUpdateBalanceChangeDto inputDto)
        {
            var result = await UpdateCardBalanceChangeByCond(inputDto);
            return (result.Item1, result.Item2);
        }

        #endregion

        #region 获取储值卡余额变化列表
        /// <summary>
        /// 获取储值卡余额变化列表
        /// </summary>
        /// <param name="searchDto"></param>
        /// <returns></returns>
        public async Task<(IEnumerable<CardBalanceChangesShowDto>, int, bool)> GetCardBalanceChanges(CardBalanceChangeSearchDto searchDto)
        {
            int pageIndex = searchDto.PageIndex;
            int pageSize = searchDto.PageSize;
            var memberNo = searchDto?.memberNo;
            var openId = searchDto?.openId;
            int total = 0;
            var isLastPage = false;

            var db = await _cardBalanceChangeRepository.GetDbContextAsync();
            var cardBalanceChanges = await db.Set<CardBalanceChangeEntity>().AsNoTracking().OrderBy(x => x.memberNo).ThenByDescending(o => o.addTime).ToListAsync();
            if (!string.IsNullOrEmpty(memberNo))
                cardBalanceChanges = cardBalanceChanges.Where(x => x.memberNo == memberNo).ToList();
            if (!string.IsNullOrEmpty(openId))
                cardBalanceChanges = cardBalanceChanges.Where(x => x.openId == openId).ToList();

            total = cardBalanceChanges.Count();
            //总页数
            var pageCount = (total + pageSize - 1) / pageSize;
            //是否最后一页
            isLastPage = pageCount <= pageIndex;
            cardBalanceChanges = cardBalanceChanges.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

            var objRet = _mapper.Map<IEnumerable<CardBalanceChangesShowDto>>(cardBalanceChanges);

            return (objRet, total, isLastPage);
        }

        #endregion

        #endregion

        #endregion

        #region private method

        #region 根据条件更新状态(仅供手机端充值使用)
        /// <summary>
        /// 根据条件更新状态
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        private async Task<bool> UpdateRechargeRecordStatusByCond(RechargeRecordUpdateStatusDto inputDto)
        {
            var result = false;
            var openId = inputDto.openId;
            var outTradeNumber = inputDto.outTradeNumber;
            var rechargeStatus = inputDto.rechargeStatus;
            //会员
            var dbPosMember = await _posMemberRepository.GetDbContextAsync();
            var posMember = await dbPosMember.Set<PosMember>().AsNoTracking().FirstOrDefaultAsync(x => x.openId == openId);
            //充值记录
            var db = await _cardRechargeRecordRepository.GetDbContextAsync();
            var cardRechargeRecord = await db.Set<CardRechargeRecordEntity>().AsNoTracking().FirstOrDefaultAsync(x => x.openId == openId && x.outTradeNumber == outTradeNumber);
            if (cardRechargeRecord != null)
            {
                using var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true);
                try
                {
                    //修改状态
                    cardRechargeRecord.rechargeStatus = rechargeStatus;
                    _entityHelper.SetUpdationInfo(cardRechargeRecord);
                    await _cardRechargeRecordRepository.UpdateAsync(cardRechargeRecord);
                    //用户余额
                    var newRechargeAmount = Math.Round((decimal)cardRechargeRecord.rechargeAmount / 100, 4, MidpointRounding.AwayFromZero);
                    var newGiftAmount = Math.Round((decimal)cardRechargeRecord.giftAmount / 100, 4, MidpointRounding.AwayFromZero);
                    posMember.cardAmount = posMember.cardAmount + newRechargeAmount;
                    posMember.presentAmount = posMember.presentAmount + newGiftAmount;
                    _entityHelper.SetUpdationInfo(posMember);
                    await _posMemberRepository.UpdateAsync(posMember);
                    //如果支付成功状态则还需要记录余额变化记录
                    if (rechargeStatus == (int)EnumOrderStatus.SUCCESS)
                    {
                        await _cardBalanceChangeRepository.InsertAsync(new CardBalanceChangeEntity()
                        {
                            changeDate = DateTime.Now.ToString("yyyy-MM-dd"),
                            changeDateTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"),
                            openId = cardRechargeRecord.openId,
                            outTradeNumber = cardRechargeRecord.outTradeNumber,
                            memberNo = cardRechargeRecord.memberNo,
                            sourceType = 1,
                            changeAmount = newRechargeAmount + newGiftAmount,
                            plusMinus = (int)EnumPlusMinus.Plus,
                            memberId = posMember.Id
                        });
                    }
                    await uow.CompleteAsync();
                    result = true;
                }
                catch (Exception e)
                {
                    await uow.RollbackAsync();
                    _logger.LogError(e.Message);
                }
            }

            return result;
        }
        #endregion

        #region 储值卡充值根据条件更新余额
        /// <summary>
        /// 储值卡充值根据条件更新余额
        /// </summary>
        /// <param name="inputDto"></param>
        /// <param name="side"></param>
        /// <returns></returns>
        private async Task<(bool, string)> UpdateRechargeRecordBalanceByCond(RechargeRecordUpdateBalanceDto inputDto, int side)
        {
            var result = false;
            var memberNo = inputDto.memberNo;
            var memberTel = inputDto?.memberTel;
            var memberId = inputDto?.memberId;
            //是否根据充值方案计算赠送金额
            var isByRechargeScheme = inputDto?.isByRechargeScheme;
            //本次充值金额
            var rechargeAmount = inputDto.rechargeAmount;
            //本次赠送金额
            var giftAmount = inputDto.giftAmount;
            if (string.IsNullOrWhiteSpace(memberId))
                return (result, "会员编号必填！");
            if (string.IsNullOrWhiteSpace(memberNo) && string.IsNullOrWhiteSpace(memberTel))
                return (result, "会员号和会员手机号必须要其中一个！");
            //会员
            var dbPosMember = await _posMemberRepository.GetDbContextAsync();
            var posMember = await dbPosMember.Set<PosMember>().AsNoTracking().FirstOrDefaultAsync(x => x.Id == memberId);//(x => x.No == memberNo);
            if (posMember == null)
                return (result, "会员不存在");

            //校验会员id对应的会员号或手机号是否一致
            if (!string.IsNullOrWhiteSpace(memberNo) && memberNo != posMember.No)
                return (result, "会员号异常！");
            if (!string.IsNullOrWhiteSpace(memberTel) && memberTel != posMember.memberTel)
                return (result, "会员手机号异常！");

            var outTradeNumber = "POS_" + memberNo + DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff");
            using var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true);
            try
            {
                int rAmount = 0, gAmount = 0;
                //如果是后台服务用直接转int,但是传入值单位是分，POS端用需要解密
                if (side == 1)
                {
                    rAmount = Convert.ToInt32(rechargeAmount);
                    gAmount = Convert.ToInt32(giftAmount);
                    //如果确认根据充值方案计算赠送金额，那重新计算赠送金额
                    if (isByRechargeScheme != null && isByRechargeScheme == true)
                    {
                        //获取充值方案。后端充值需要根据充值方案来进行赠送
                        var db = await _cardRechargeSchemeRepository.GetDbContextAsync();
                        var cardRechargeSchemes = await db.Set<CardRechargeSchemeEntity>().AsNoTracking().Where(x => x.IsDeleted == false).OrderByDescending(x => x.updateTime).ToListAsync();
                        //这边只获取最新的一条方案进行计算赠送金额
                        var cardRechargeScheme = cardRechargeSchemes?.FirstOrDefault();
                        if (!object.Equals(cardRechargeScheme, null))
                        {
                            //充值方案充值金额
                            var schemeRechargeAmount = cardRechargeScheme.rechargeAmount;
                            //充值方案赠送金额
                            var schemeGiftAmount = cardRechargeScheme.giftAmount;
                            if (rAmount >= schemeRechargeAmount)
                            {
                                //只有充值金额大于等于充值方案充值金额才计算赠送金额
                                gAmount = rAmount / schemeRechargeAmount * schemeGiftAmount;
                            }
                        }
                    }
                }
                else
                {
                    rAmount = Convert.ToInt32(Base64EncodeHelper.DeCodeBase65(rechargeAmount));
                    gAmount = Convert.ToInt32(Base64EncodeHelper.DeCodeBase65(giftAmount));
                }
                //本次充值金额
                var newRechargeAmount = Math.Round((decimal)rAmount / 100, 4, MidpointRounding.AwayFromZero);
                //本次赠送金额
                var newGiftAmount = Math.Round((decimal)gAmount / 100, 4, MidpointRounding.AwayFromZero);
                //充值后卡内可用金额
                posMember.cardAmount = posMember.cardAmount + newRechargeAmount;
                //充值后卡内可用赠送金额
                posMember.presentAmount = posMember.presentAmount + newGiftAmount;
                posMember.updateTime = DateTime.Now;
                _entityHelper.SetUpdationInfo(posMember);
                await _posMemberRepository.UpdateAsync(posMember);

                //新增支付记录
                var cardRechargeRecord = new CardRechargeRecordEntity()
                {
                    rechargeDate = DateTime.Now.ToString("yyyy-MM-dd"),
                    rechargeDateTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"),
                    outTradeNumber = outTradeNumber,
                    openId = posMember.openId,
                    memberNo = memberNo,
                    rechargeAmount = rAmount,
                    giftAmount = gAmount,
                    rechargeStatus = 0,
                    remark = inputDto.remark,
                    memberId = posMember.Id,
                    payWay = 3
                };
                _entityHelper.InitEntity(cardRechargeRecord);
                await _cardRechargeRecordRepository.InsertAsync(cardRechargeRecord);
                //支付成功状态则还需要记录余额变化记录
                var cardBalanceChange = new CardBalanceChangeEntity()
                {
                    changeDate = DateTime.Now.ToString("yyyy-MM-dd"),
                    changeDateTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"),
                    openId = cardRechargeRecord.openId,
                    outTradeNumber = cardRechargeRecord.outTradeNumber,
                    memberNo = cardRechargeRecord.memberNo,
                    sourceType = 1,
                    changeAmount = newRechargeAmount + newGiftAmount,
                    plusMinus = (int)EnumPlusMinus.Plus,
                    memberId = posMember.Id
                };
                _entityHelper.InitEntity(cardBalanceChange);
                await _cardBalanceChangeRepository.InsertAsync(cardBalanceChange);

                await uow.CompleteAsync();
                result = true;
            }
            catch (Exception e)
            {
                await uow.RollbackAsync();
                _logger.LogError(e.Message);
                return (false, e.Message);
            }

            return (result, null);
        }
        #endregion

        #region 储值卡余额使用-更新余额（仅供POS端使用）
        /// <summary>
        /// 储值卡余额使用-更新余额（仅供POS端使用）
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        private async Task<(bool, string)> UpdateCardBalanceChangeByCond(CardUpdateBalanceChangeDto inputDto)
        {
            var result = false;
            var memberNo = inputDto.memberNo;
            var cardUseAmount = inputDto.cardUseAmount;
            //会员
            var dbPosMember = await _posMemberRepository.GetDbContextAsync();
            var posMember = await dbPosMember.Set<PosMember>().AsNoTracking().FirstOrDefaultAsync(x => x.No == memberNo);
            if (posMember == null)
                return (result, "会员不存在");

            var cuAmount = 0;
            ////开发环境不加密
            //if (_environment.IsDevelopment())
            //    cuAmount = Convert.ToInt32(cardUseAmount);
            //else
            //    cuAmount = Convert.ToInt32(Base64EncodeHelper.DeCodeBase65(cardUseAmount));
            cuAmount = Convert.ToInt32(Base64EncodeHelper.DeCodeBase65(cardUseAmount));
            var cardAmount = posMember.cardAmount;
            var presentAmount = posMember.presentAmount;
            //校验余额是否充足
            if (((decimal)cuAmount / 100) > cardAmount + presentAmount)
                return (result, "余额不足");

            var outTradeNumber = "USE_" + memberNo + DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff");
            using var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true);
            try
            {
                //用户消费余额
                var newConsumeAmount = Math.Round((decimal)cuAmount / 100, 4, MidpointRounding.AwayFromZero);
                
                //先使用本金
                if (newConsumeAmount >= cardAmount)
                {
                    posMember.cardAmount = 0;
                    posMember.presentAmount = posMember.presentAmount - (newConsumeAmount - cardAmount);
                }
                else
                {
                    posMember.cardAmount = posMember.cardAmount - newConsumeAmount;
                }
                posMember.updateTime = DateTime.Now;
                _entityHelper.SetUpdationInfo(posMember);
                await _posMemberRepository.UpdateAsync(posMember);

                //支付成功状态则还需要记录余额变化记录
                var cardBalanceChange = new CardBalanceChangeEntity()
                {
                    changeDate = DateTime.Now.ToString("yyyy-MM-dd"),
                    changeDateTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"),
                    openId = posMember.openId,
                    outTradeNumber = outTradeNumber,
                    memberNo = posMember.No,
                    sourceType = 2,
                    changeAmount = newConsumeAmount,
                    plusMinus = (int)EnumPlusMinus.Minus,
                    memberId = posMember.Id
                };
                _entityHelper.InitEntity(cardBalanceChange);
                await _cardBalanceChangeRepository.InsertAsync(cardBalanceChange);

                await uow.CompleteAsync();
                result = true;
            }
            catch (Exception e)
            {
                await uow.RollbackAsync();
                _logger.LogError(e.Message);
                return (false, e.Message);
            }

            return (result, null);
        }
        #endregion

        #endregion
    }
    #endregion
}
